home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xpaint-2.1.1
/
misc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
6KB
|
289 lines
/* +-------------------------------------------------------------------+ */
/* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
/* | | */
/* | Permission to use, copy, modify, and to distribute this software | */
/* | and its documentation for any purpose is hereby granted without | */
/* | fee, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. There is no | */
/* | representations about the suitability of this software for | */
/* | any purpose. this software is provided "as is" without express | */
/* | or implied warranty. | */
/* | | */
/* +-------------------------------------------------------------------+ */
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/cursorfont.h>
#include <X11/Xaw/Label.h>
#include <ctype.h>
#include "bitmaps/background.xbm"
#ifndef XtNcursor
#define XtNcursor "cursor"
#endif
#include "xpaint.h"
Widget GetToplevel(Widget w)
{
Widget p = w;
while (w != None) {
p = w;
w = XtParent(w);
}
return p;
}
Widget GetShell(Widget w)
{
while (!XtIsShell(w))
w = XtParent(w);
return w;
}
void SetIBeamCursor(Widget w)
{
XtVaSetValues(w, XtVaTypedArg,
XtNcursor, XtRString, "xterm", sizeof(Cursor), NULL);
}
void SetCrossHairCursor(Widget w)
{
XtVaSetValues(w, XtVaTypedArg,
XtNcursor, XtRString, "crosshair", sizeof(Cursor), NULL);
}
void SetPencilCursor(Widget w)
{
XtVaSetValues(w, XtVaTypedArg,
XtNcursor, XtRString, "pencil", sizeof(Cursor), NULL);
}
/*
** Some useful XRectangle computation code.
*/
XRectangle *RectUnion(XRectangle *a, XRectangle *b)
{
static XRectangle out;
int sx, ex, sy, ey;
sx = MIN(a->x, b->x);
sy = MIN(a->y, b->y);
ex = MAX(a->x + a->width, b->x + b->width);
ey = MAX(a->y + a->height, b->y + b->height);
XYtoRECT(sx, sy, ex, ey, &out);
return &out;
}
XRectangle *RectIntersect(XRectangle *a, XRectangle *b)
{
static XRectangle out;
int w, h;
if (a == NULL || b == NULL)
return NULL;
out.x = MAX(a->x, b->x);
out.y = MAX(a->y, b->y);
w = MIN(a->x + a->width, b->x + b->width) - out.x;
h = MIN(a->y + a->height, b->y + b->height) - out.y;
if (w <= 0 || h <= 0)
return NULL;
out.width = w;
out.height = h;
return &out;
}
/*
**
*/
void GetPixmapWHD(Display *dpy, Drawable d, int *wth, int *hth, int *dth)
{
Window root;
int x, y;
unsigned int width, height, bw, depth;
XGetGeometry(dpy, d, &root, &x, &y, &width, &height, &bw, &depth);
if (wth != NULL) *wth = width;
if (hth != NULL) *hth = height;
if (dth != NULL) *dth = depth;
}
/*
** Two useful functions to "cache" both a tiled background
** and a Xor gc
*/
typedef struct bgList_s {
int depth;
Pixmap pixmap;
struct bgList_s *next;
} BackgroundList;
static BackgroundList *bgList = NULL;
Pixmap GetBackgroundPixmap(Widget w)
{
Widget p, n;
Display *dpy = XtDisplay(w);
int depth;
Pixmap pix;
Pixel fg, bg;
BackgroundList *cur;
Widget tw;
for (n = XtParent(p=w); !XtIsShell(n); n = XtParent(p=n));
XtVaGetValues(p, XtNdepth, &depth, NULL);
for (cur = bgList; bgList != NULL; bgList = bgList->next)
if (cur->depth == depth)
return cur->pixmap;
tw = XtVaCreateWidget("junkWidget", labelWidgetClass, w,
XtNwidth, 1,
XtNheight, 1,
NULL);
XtVaGetValues(tw, XtNforeground, &fg,
XtNbackground, &bg,
NULL);
XtDestroyWidget(tw);
pix = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
(char *)background_bits,
background_width, background_height,
bg,fg, depth);
cur = XtNew(BackgroundList);
cur->next = bgList;
bgList = cur;
cur->depth = depth;
cur->pixmap = pix;
return pix;
}
typedef struct gcList_s {
Widget widget;
int depth;
GC gc;
struct gcList_s *next;
} GCXList;
static GCXList *gcList = NULL;
GC GetGCX(Widget w)
{
Widget n = GetShell(w);
int depth;
GCXList *cur;
XGCValues values;
XtVaGetValues(n, XtNdepth, &depth, NULL);
for (cur = gcList; gcList != NULL; gcList = gcList->next)
if (cur->depth == depth)
return cur->gc;
values.function = GXxor;
values.foreground = 1;
cur = XtNew(GCXList);
cur->next = gcList;
gcList = cur;
cur->depth = depth;
cur->gc = XtGetGC(n, GCFunction|GCForeground, &values);
return cur->gc;
}
/*
** Argv parsing routines
*/
static char *nextArg(char *str, char **start)
{
char *cp;
int flg;
while (isspace(*str))
str++;
if (start != NULL)
*start = str;
if (*str == '\0')
return NULL;
if (*str == '\'' || *str == '"') {
char delim = *str;
if (start != NULL)
(*start)++;
cp = ++str;
while (*str != '\0' && *str != delim) {
if (*str == '\\') {
if (*++str == '\0')
continue;
}
*cp++ = *str++;
}
*cp = '\0';
} else {
while (!isspace(*str) && *str != '\0')
str++;
}
flg = (*str != '\0');
*str = '\0';
return str + (flg ? 1 : 0);
}
void StrToArgv(char *str, int *argc, char **argv)
{
int t;
char *cp;
if (argc == NULL)
argc = &t;
*argc = 0;
for (cp = str; cp != NULL; (*argc)++)
cp = nextArg(cp, argv == NULL ? NULL : &argv[*argc]);
if (argv != NULL)
argv[--(*argc)] = NULL;
}
/*
** Create a XImage
*/
XImage *NewXImage(Display *dpy, Visual *visual, int depth, int width, int height)
{
XImage *xim;
int pad;
if (depth > 16)
pad = 32;
else if (depth > 8)
pad = 16;
else
pad = 8;
xim = XCreateImage(dpy, visual, depth, ZPixmap, 0, NULL, width, height, pad, 0);
if (xim == NULL)
return NULL;
xim->data = (char*)XtMalloc(xim->bytes_per_line * height);
if (xim->data == NULL) {
XDestroyImage(xim);
xim = NULL;
}
return xim;
}